<?php

namespace app\models;

use app\components\helpers\TreeHelper;
use Yii;
use yii\db\Exception;
use yii\behaviors\TimestampBehavior;

/**
 * 权限项模型
 * @property int $id 主键
 * @property int $parent_id 上级
 * @property string $name 名称
 * @property string $route 路由
 * @property int $data_auth 数据过滤
 * @property int $status 状态
 * @property string $remark 备注
 * @property string $path 层级路径
 * @property int $created_at 创建时间
 * @property int $updated_at 更新时间
 *
 */
class Item extends ActiveRecord
{
    const DATA_AUTH_NO = 0;
    const DATA_AUTH_YES = 1;

    public static function getDataAuthMapping()
    {
        return [
            self::DATA_AUTH_YES => '需要',
            self::DATA_AUTH_NO => '不需要'
        ];
    }

    public static function tableName()
    {
        return '{{%item}}';
    }

    public function behaviors()
    {
        return [['class' => TimestampBehavior::class]];
    }

    public function rules()
    {
        return [[['parent_id', 'name', 'route', 'data_auth', 'status', 'remark'], 'safe']];
    }

    /**
     * 新增时，设置 path 值
     * @param bool $insert
     * @param array $changedAttributes
     */
    public function afterSave($insert, $changedAttributes)
    {
        if ($insert) {
            $this->path = $this->parent_id ? $this->getParent()->path . '_' . $this->id : $this->id;
            $this->save(false);
        }
    }

    /**
     * 查询上级权限项
     * @return array|\yii\db\ActiveRecord|null
     */
    public function getParent()
    {
        return self::find()->where(['id' => $this->parent_id])->one();
    }

    /**
     * 查询下级权限项数量统计
     * @return bool|int|string|null
     */
    public function getChildrenCount()
    {
        return $this->hasMany(Item::class, ['parent_id' => 'id'])->count('id');
    }

    /**
     * 设置所有下级权限项的状态值
     * @param $status
     */
    public function setChildrenStatus($status)
    {
        self::updateAll(['status' => $status], ['like', 'path', $this->id . '_']);
    }

    /**
     * 删除权限项
     * @throws \Throwable
     */
    public function performDelete()
    {
        $db = app()->getDb();
        $trans = $db->beginTransaction();
        try {
            // 自身删除
            $this->delete();

            // 删除 权限项、 将角色、岗位、个人 有赋予此权限 的 删除掉
            $this->removeForUser();
            $this->removeForRole();
            $this->removeForPosition();

            $trans->commit();
        } catch (Exception $e) {
            $trans->rollBack();
        }
    }

    /**
     * 移除用户下的权限项
     */
    public function removeForUser()
    {
        UserItem::deleteAll(['item_id' => $this->id]);
    }

    /**
     * 移除角色下的权限项
     */
    public function removeForRole()
    {
        RoleItem::deleteAll(['item_id' => $this->id]);
        RoleItemDefault::deleteAll(['item_id' => $this->id]);
    }

    /**
     * 移除岗位下的权限项
     */
    public function removeForPosition()
    {
        PositionItem::deleteAll(['item_id' => $this->id]);
        PositionItemDefault::deleteAll(['item_id' => $this->id]);
    }

    /**
     * 查询所有权限项，并统计其下 用户 & 角色 数量
     * @param int $parentId
     * @return array|\yii\db\ActiveRecord[]
     */
    public static function getListWithUserAndRoleCount($parentId = 0)
    {
        // 子查询 用户统计
        $userQuery = UserItem::find();
        $userQuery->select('COUNT(*)');
        $userQuery->where('ui.item_id = i.id');
        $userQuery->asArray();
        $userQuery->alias('ui');

        // 子查询 角色统计
        $roleQuery = RoleItem::find();
        $roleQuery->select('COUNT(*)');
        $roleQuery->where('ri.item_id = i.id');
        $roleQuery->asArray();
        $roleQuery->alias('ri');

        // 权限项查询
        $query = self::find();
        $query->select([
            'id',
            'parent_id AS parentId',
            'name',
            'status',
            'userCount' => $userQuery,
            'roleCount' => $roleQuery
        ]);
        $parentId > 0 ? $query->where(['like', 'path', $parentId]) : '';
        $query->asArray()->alias('i');
        return $query->all();
    }

    /**
     * 查询顶级的权限项列表
     * @return array|\yii\db\ActiveRecord[]
     */
    public static function getTopList()
    {
        $query = self::find();
        $query->where(['parent_id' => 0]);
        $query->select(['id', 'name']);
        return $query->asArray()->all();
    }

    /**
     * 查询所有权限项、格式为下拉列表
     * @return array
     */
    public static function getDropList()
    {
        $itemArr = self::find()->select(['id', 'parent_id AS parentId', 'name'])->asArray()->all();
        return TreeHelper::format($itemArr);
    }

    /**
     * 查询所有权限项为 角色、岗位、个人用户 授权使用
     * @return array
     */
    public static function getListForAuth()
    {
        $query = self::find();
        $query->select([
            'id',
            'name',
            'parent_id AS parentId',
            'data_auth AS auth',
            '(0) AS type',
            '(0) AS checked',
            'status'
        ]);
        $query->asArray();
        $itemArr = $query->all();
        return array_combine(array_column($itemArr, 'id'), array_values($itemArr));
    }

}